<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs 
		title="__UP_title__"
		description = "Use Google Maps to show your the locations of your recent website visitors together with a selection of regional images using a feed from www.getclicky.com."
		height="250"
		author="Bonstio"
		author_email="bonstio+maps@gmail.com"
		directory_title="Visitor Map"
		title_url="http://bonstio.net/clicky"
		author_location="Bath, UK" 
		category="Tools"
		screenshot="http://visitormap.googlecode.com/svn/trunk/images/visitorMapClicky.png"
		thumbnail="http://visitormap.googlecode.com/svn/trunk/images/visitorMap_thumb.png">
		<Require feature="setprefs" /> 
		<Require feature="dynamic-height"/>
		<Require feature="analytics"/>
 </ModulePrefs> 
<UserPref name="title" display_name="Gadget title" required="false" default_value="Clicky Visitor Map"/>
<UserPref display_name="Clicky base API URL" name="stored_visitor_url" default_value="http://s1.getclicky.com/stats/api?site_id=10&amp;sitekey=aec3874187f5"/>
<UserPref name="gadgetHeight" display_name="Gadget height" datatype="enum" default_value="450">
  <EnumValue value="250"/>
  <EnumValue value="300"/>
  <EnumValue value="350"/>
  <EnumValue value="400"/>
  <EnumValue value="450"/>
  <EnumValue value="500"/>
  <EnumValue value="550"/>
  <EnumValue value="600"/>
</UserPref>
<UserPref name="map_location" datatype="hidden" default_value="49.15297,0.703125"/>
<UserPref name="map_zoom" datatype="hidden" default_value="2"/>
<UserPref datatype="hidden" name="visitor_url"/>

<UserPref name="thumbGrid" display_name="Thumb grid" default_value="4" datatype="enum">
	<EnumValue display_value="Off" value="0"/>	
	<EnumValue display_value="1" value="1"/>
	<EnumValue display_value="2 x 2" value="2"/>
	<EnumValue display_value="3 x 3" value="3"/>
	<EnumValue display_value="4 x 4" value="4"/>
	<EnumValue display_value="5 x 5" value="5"/>
	<EnumValue display_value="6 x 6" value="6"/>
	<EnumValue display_value="7 x 7" value="7"/>
</UserPref>

<UserPref name="thumbGridWidth" display_name="Thumb grid width" default_value="108" datatype="enum">
  <EnumValue display_value="100" value="108"/>
  <EnumValue display_value="120" value="120"/>
  <EnumValue display_value="140" value="140"/>
  <EnumValue display_value="160" value="160"/>
  <EnumValue display_value="180" value="180"/>
  <EnumValue display_value="200" value="200"/>
  <EnumValue display_value="220" value="220"/>
</UserPref>

<UserPref name="mapType" display_name="Default map type" default_value="G_NORMAL_MAP" datatype="enum">
	<EnumValue display_value="Map" value="G_NORMAL_MAP"/>	
	<EnumValue display_value="Satellite" value="G_SATELLITE_MAP"/>
	<EnumValue display_value="Hybrid" value="G_HYBRID_MAP"/>
</UserPref>

<UserPref name="miniMapControls" display_name="Inset controls" default_value="0" datatype="enum">
	<EnumValue display_value="None" value="0"/>
	<EnumValue display_value="Zoom controls only" value="1"/>
	<EnumValue display_value="Zoom controls and map type" value="2"/>
</UserPref>
<UserPref display_name="Preview images on hover" name="showImage" default_value="false" datatype="bool"/>
<UserPref display_name="Show link to view session on Clicky" name="showMore" default_value="true" datatype="bool"/>
  <Content type="html">
  <![CDATA[ 
    <div id="map" style="width: 100%; height:__UP_gadgetHeight__px;">&nbsp;</div>
    <div id="locationDiv" style="width: 100%; height: 200px; position:absolute; top:30px; left:0px; display:none; border-top:1px #cccccc solid; border-bottom:1px #cccccc solid; background-color: #ffffff;">&nbsp;</div>
	
    <script src="http://maps.google.com/maps?file=api&amp;v=2" type="text/javascript"></script>
    <script src="http://visitormap.googlecode.com/svn/trunk/js/dragzoom_packed.js" type="text/javascript"></script>    
    <script src="http://www.daylightmap.com/daylight_packed.js" type="text/javascript"></script>
	<script type="text/javascript">

		function Marker(item)
		{	
			this.onGotImages = function(response)
			{
				var expected = '{\"ResultSet\":{';
				if (response.substring(0, expected.length) == expected)
				{
					var obj = eval( '(' + response + ')' );
					var results = obj.ResultSet.Result;
					mapGadget.thumbsLoaded = results.length;

					var dimension = Math.floor(Math.sqrt(mapGadget.thumbCount));
					var imgSize = Math.floor( (mapGadget.paneWidth - 1* dimension)/ dimension) - 2;
					var table = '<span></span><table style="width:' + mapGadget.paneWidth  + 'px;" cellspacing ="1" cellpadding="0">';
					for (var i=0; i< results.length; i+=dimension)
					{
						table += mapGadget.getRow(results, i, i + dimension, imgSize);
					}
					table += '</table>';

					var thumbTable = _gel("thumbs" + mapGadget.id);
					if (thumbTable)
					{
						thumbTable.innerHTML = table;					
					}
				}
			};
		}

		var mapGadget = 
		{
			prefs : new Object(),

			source :  "",
			stored_source :  "",

			map : new GMap2(_gel("map")),
			items : new Array(),

			paneWidth : 200,

			marker : new Object(),
			markerHTML : "",
			id : -1,

			cached : true,
			imageArray : new Array(),
			loadedImages : 0,

			thumbsLoaded : 0,
			thmubTable : "",
			thumbCount : 16,

			imageFeed : "http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=AyfZsPDV34E4NtYkfxBPYIz7GaiSP2rgJSZJMwRhUNnAT0vrPi.P08OJbXB1HzfgMg--",
			isIG : false,

			getUserPrefs : function()
			{
				mapGadget.source = mapGadget.prefs.getString("visitor_url");
				mapGadget.stored_source = mapGadget.prefs.getString("stored_visitor_url");

				var thumbCount = mapGadget.prefs.getInt("thumbGrid");
				mapGadget.thumbCount = thumbCount * thumbCount;

				mapGadget.paneWidth = mapGadget.prefs.getInt("thumbGridWidth");

				if ((mapGadget.source == null) || (mapGadget.source == ""))
				{	
					mapGadget.isIG = true;
					_IG_AdjustIFrameHeight();
				}
			},

			getVisitorData : function()
			{
				var url = mapGadget.source;
			
				//if not on a webpage
				if (mapGadget.isIG)
				{
					url = mapGadget.stored_source

					//store last location - otherwise permission denied : Window.setProperty
					GEvent.addListener(mapGadget.map, "moveend", function() 
					{
						var center = mapGadget.map.getCenter();
						mapGadget.prefs.set("map_location", center.toUrlValue());
						mapGadget.prefs.set("map_zoom", mapGadget.map.getZoom());
					});
				}
				else
				{
					url = decodeURIComponent(url);
				}

				url += "&output=js&type=visitors-list&limit=100";
				url = encodeURI(url);

				_IG_FetchContent(url, mapGadget.onGotVisitorData);
			},

			onGotVisitorData : function(response)
			{
				var data = new Object();


				if ((response == null) || (response == ""))
				{
				    return;
				}

				eval("data = " + response + ";");

				if (data.length > 0)
				{
					//store response object
					mapGadget.data = data;
					
					//for each visitor
					for (var i=0; i<data.length; i++)
					{
						var item = data[i];
						mapGadget.items[i] = data[i];

						//I somtimes see a lat/long pair of (0,0) returned by Clicky. This check prevents it getting plotted
						var nullLatLongCheck = parseFloat(item.latitude) + parseFloat(item.longitude);

						if ((item) && (nullLatLongCheck != 0))
						{
							var locationString = item.geolocation;
						
							var url = mapGadget.imageFeed + "&results=" + mapGadget.thumbCount;
							url += "&output=json";
							url += "&query=" + encodeURIComponent(locationString);
				
							var clickyUrl = item.url_clicky;

							mapGadget.markerHTML = mapGadget.getMarkerHTML(i, locationString, item.date_pretty, clickyUrl);
							
							var point = new GLatLng(item.latitude, item.longitude);
							mapGadget.marker = mapGadget.createMarker(point, i, mapGadget.markerHTML);						
							mapGadget.map.addOverlay(mapGadget.marker);
						}
					}
				}
			},


			renderMap : function()
			{
				var mapZoom = mapGadget.prefs.getInt("map_zoom");
				var mapLocation = mapGadget.prefs.getString("map_location");
				
            var daylight = new daylightLayer();
            daylight.cityLights = true;
            daylight.addToMap(mapGadget.map);
				if (mapLocation == "")
				{
					mapLocation = new GLatLng(0,0);
				}
				else
				{
					coords = mapLocation.split(",");
					mapLocation = new GLatLng(_trim(coords[0]), _trim(coords[1]));
				}

				var otherOpts =
                    {
                      buttonHTML: "<img src='http://visitormap.googlecode.com/svn/trunk/images/zoom-button.gif' />",
                      buttonZoomingHTML: "<img src='http://visitormap.googlecode.com/svn/trunk/images/zoom-button-activated.gif' />",
                      buttonStartingStyle: {width: '24px', height: '24px'}
                    };

				mapGadget.map.setCenter(mapLocation, mapZoom, __UP_mapType__);
                mapGadget.map.addControl(new GSmallZoomControl());
                mapGadget.map.addControl(new DragZoomControl({}, otherOpts, {}), new GControlPosition(G_ANCHOR_BOTTOM_LEFT,new GSize(10,10)));
				mapGadget.map.addControl(new GMapTypeControl());

				mapGadget.map.enableDoubleClickZoom();
				mapGadget.map.enableContinuousZoom();

			},

			addPoint : function()
			{

			},

			createMarker : function(point, i, text)
			{
				mapGadget.marker = text;
				var marker = new GMarker(point);

					// Show this marker's index in the info window when it is clicked
					try
					{
						GEvent.addListener(marker, "click", function() 
						{ 
							//if on iGoogle
							var container;
							//if (mapGadget.isIG)
							if (false)
							{
								var gadgetDiv = _gel("locationDiv");
								gadgetDiv.style.display = "";
								gadgetDiv.innerHTML = text;
								container = _gel("miniMap");

								var close = new Image();
								close.src = _IG_GetImageUrl("http://www.google.com/intl/en_ALL/mapfiles/close.gif");
								close.style.position = "absolute";
								close.style.right = "2px";
								close.style.top = "2px";
								close.style.cursor = "pointer";

								close.onclick = function()
								{
									gadgetDiv.style.display = "none";
									gadgetDiv.innerHTML = "";
								};
								gadgetDiv.appendChild(close);
							}
							else
							{
								marker.openInfoWindowHtml(text);
								container = _gel("miniMap" + i);
							}

							container = _gel("miniMap" + i);

							var minimap = new GMap(container);
							minimap.setMapType(__UP_mapType__);
							minimap.enableDoubleClickZoom();
				            minimap.enableContinuousZoom();
							minimap.setCenter(point, 11);
							minimap.setMapType(__UP_mapType__);

							var miniMapMarker = new GMarker(point);
							minimap.addOverlay(miniMapMarker);

							if (__UP_miniMapControls__ > 0)
							{
								minimap.addControl(new GSmallZoomControl());
							}

							if (__UP_miniMapControls__ > 1)
							{
								minimap.addControl(new GMapTypeControl());
							}

							if (mapGadget.thumbCount > 0)
							{
								mapGadget.loadedImages = 0;
								mapGadget.getThumbTable(mapGadget.items, i);
							}

						});
					}
					catch (err)
					{
					}

				return marker;
			},

			addImageSearch : function()
			{
				GEvent.addListener(mapGadget.map, "moveend", function()
				{
				  var center = mapGadget.map.getCenter();
				});

			},

			getMarkerHTML : function (i, locationString, date, clickyUrl)
			{
				//var tableWidth = mapGadget.isIG ? 'width:100%;' : '';

				var pw = mapGadget.isIG ? '100%' : (mapGadget.paneWidth - 2) + 'px';
				var infoWindowWidth =  mapGadget.paneWidth;

				var thumbCell = '&nbsp';
				if (mapGadget.thumbCount > 0)
				{
					thumbCell = '<div class="wraptocenter"><span></span><div style="text-align:center; width: '+mapGadget.paneWidth+'px; height: '+mapGadget.paneWidth+'px;" id="thumbs' + i +'">Loading images...</div></div>';
					infoWindowWidth = infoWindowWidth * 2;
				}
				else
				{
					infoWindowWidth = 200;
				}

				var miniMapWidth = (mapGadget.thumbCount > 0) ?  mapGadget.paneWidth : 200;


				var marker =	'<div id="infowindow" style="background-color:white; font-size:80%; padding-right:10px; width:' +  infoWindowWidth + 'px;">';
				marker +=			'<div style="text-align:left; width:' + infoWindowWidth +'px;">';
				marker +=				'Somebody in <b>' + locationString +'</b> visited';
				marker +=				'<br/>';
				marker +=				'on <b>' + date + '</b>';

				marker +=			'</div>';
				marker +=			'<div style="text-align:right;">';
				marker +=				'<table cellpadding="0" cellspacing="1" style="width:' + infoWindowWidth +'px;">';
				marker +=				'<tr>';
				marker +=					'<td valign="middle">';
				marker +=						'<div style="width:' + mapGadget.paneWidth + 'px; text-align:center; overflow:hidden; height: '+(mapGadget.paneWidth)+'px;" id="miniMap' + i + '">&nbsp;</div>';
				marker +=					'</td>';
				marker +=					'<td valign="middle">';
				marker +=						thumbCell;
				marker +=					'</td>';
				marker +=				'</tr>';
				marker +=				'</table>';
             	if (__UP_showMore__)
				{
				    marker +=           '<a target="_blank" href="'  + clickyUrl + '">View this session on Clicky...</a>';
				}
				marker +=			'</div>';

				marker +=		'</div>';
	
				return marker;
			},

			getImageThumb : function(results, i, size)
			{
				var result = results[i];

				if (__UP_showImage__)
				{
					mapGadget.imageArray[i] = new Image();
					mapGadget.imageArray[i].src = (mapGadget.cached ? _IG_GetImageUrl(result.Url) : result.Url);
				}

				var thumb =	'<a class="thumbnail" target="_top" href="' + result.Url +'">' +
							'<span></span><img onload="mapGadget.checkLoaded()"' +
							'class="thumb" src="' + (mapGadget.thumbCount > 1 ? result.Thumbnail.Url : result.Url) + '" width="' + size + '" height="' + size + '"'+
							'title="' + result.Summary + '"/>';
				if (__UP_showImage__)
				{
					thumb += '<span>';
					thumb += mapGadget.thumbCount > 1 ? '<img src="' + mapGadget.imageArray[i].src +'"/>' : '';
					thumb += '<span>';
				}
				thumb += '</a>';

				return thumb;
			},

			checkLoaded : function(e)
			{
				 mapGadget.loadedImages++;
				 if (mapGadget.loadedImages == mapGadget.thumbsLoaded)
				 {
					//console.log("done");
				 }
			},

			getCell : function(results, i, size)
			{
					var result = results[i];
				
					var cell = '<td style="display: table-cell; vertical-align: middle; width:'+size+'px; height:'+size+'px;">' + 
									'<div class="wraptocenter" style="height:'+size+'">' + 
										(result ? mapGadget.getImageThumb(results, i, size) : '&nbsp') + 
								'	</div>' + 
								'</td>';
					return cell;
			},

			getRow : function(results, start, limit, imgSize)
			{
				var row = '<tr>';
				for (var i=start; i<limit; i++)
				{
					row += mapGadget.getCell(results, i, imgSize);
				}
				row += '</tr>';
				return row;
			},
				
			getThumbTable : function (locationResults, i)
			{
				var locationResult = locationResults[i];
				var locationString = locationResult.geolocation;

				var url = mapGadget.imageFeed + "&results=" + mapGadget.thumbCount;
				url += "&output=json";
				url += "&query=" + encodeURIComponent(locationString);
				
				mapGadget.id = i

				_IG_FetchContent(url, new Marker(locationResult).onGotImages);


			},

			main : function()
			{
				if (GBrowserIsCompatible())
				{
					mapGadget.prefs = new _IG_Prefs(__MODULE_ID__);
					mapGadget.renderMap();
					mapGadget.getUserPrefs();

					//_gel("map").style.height = mapGadget.prefs.getInt("gadgetHeight");
					
					//mapGadget.addImageSearch();
					mapGadget.getVisitorData();
				}
				_IG_Analytics("UA-582167-18", "/");
			}
		};

	  _IG_RegisterOnloadHandler(mapGadget.main());
  
    </script>
	<style>
	v\:*
	{
	    behavior:url(#default#VML);
	}

.thumb
{
	border : 0px;
	overflow : hidden;
	vertical-align:middle;
	text-align:center;
}

.thumbnail{
position: relative;
z-index: 0;
}

.thumbnail:hover{
background-color: transparent;
z-index: 50;
}

.thumbnail span{ /*CSS for enlarged image*/
position: absolute;
background-color: white;
padding: 0px;
left: -1000px;
border: 0px;
visibility: hidden;
color: black;
text-decoration: none;
}

.thumbnail span img{ /*CSS for enlarged image*/
border-width: 0;
padding: 8px;
width:175px;
}

.thumbnail:hover span{ /*CSS for enlarged image on hover*/
visibility: visible;
top: 0;
left: 60px; /*position where enlarged image should offset horizontally */
z-index: 1000;

}

.wraptocenter {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
    width: ...;
    height: ...;
}
.wraptocenter * {
    vertical-align: middle;
}
/*\*//*/
.wraptocenter {
    display: block;
}
.wraptocenter span {
    display: inline-block;
    height: 100%;
    width: 1px;
}
	</style>
  ]]> 
  </Content>
</Module>  
